package thu.cs.segroup.parser;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import thu.cs.segroup.entity.TestCase;
import thu.cs.segroup.entity.TestCaseConfig;
import thu.cs.segroup.util.Constants;

public class TestCaseParser {

	public static TestCase parsrTestCase(File test_case_xml_file) {
		Document doc;
		SAXReader reader = new SAXReader();
		TestCase ws_case = null;
		try {
			doc = reader.read(test_case_xml_file);
			Element root = doc.getRootElement();
			ws_case = new TestCase();
			Node id = root.selectSingleNode(Constants.XML_TEST_CASE_ID);
			if (id != null) {
				// System.out.println(id.getStringValue());
				ws_case.setId(id.getStringValue());
			}
			Node inputTypes = root.selectSingleNode(Constants.XML_TEST_CASE_INPUTTYPES);
			if (inputTypes != null ) {
				// System.out.println(inputTypes.getStringValue());
				ws_case.setInputTypes(inputTypes.getStringValue());
			}
			Node outputTypes = root.selectSingleNode(Constants.XML_TEST_CASE_OUTPUTTUPES);
			if (outputTypes != null) {
				// System.out.println(outputTypes.getStringValue());
				ws_case.setOutput(outputTypes.getStringValue());
			}
			Node category = root.selectSingleNode(Constants.XML_TEST_CASE_CATEGORY);
			if (category != null) {
				// System.out.println(category.getStringValue());
				ws_case.setCategory(category.getStringValue());
			}
			Node service_id = root.selectSingleNode(Constants.XML_TEST_CASE_SERVICE_ID);
			if (service_id != null ) {
				ws_case.setService_id(service_id.getStringValue());
			}
			Node method = root.selectSingleNode(Constants.XML_TEST_CASE_METHOD);
			if (method != null) {
				ws_case.setMethod(method.getStringValue());
			}
			List<Element> props = root.selectNodes(Constants.XML_TEST_CASE_PROPERTIES_PATH);
			if (props.size() > 0) {
				for (int i = 0; i < props.size(); i++) {
					String key = props.get(i).attributeValue(Constants.XML_TEST_CASE_PROP_PROP_NAME);
					Object value = convertStrToObj(props.get(i).attributeValue(Constants.XML_TEST_CASE_PROP_PROP_VALUE),
							props.get(i).attributeValue(Constants.XML_TEST_CASE_PROP_DATA_TYPE));
					ws_case.addProperty(key, value);
				}
			}
			List<Element> configs = root.selectNodes(Constants.XML_TEST_CASE_CONFIGS_PATH);
			if (configs.size() > 0) {
				for (int i = 0; i < configs.size(); i++) {
					TestCaseConfig config = new TestCaseConfig();
					config.setHost(configs.get(i).attributeValue(Constants.XML_TEST_CASE_CONFIGS_HOST));
					config.setThreadCount(Integer.parseInt(configs.get(i).attributeValue(Constants.XML_TEST_CASE_CONFIGS_THREADCOUNT)));
					ws_case.addConfig(config);
				}
			}
		} catch (DocumentException e) {
			e.printStackTrace();
			return null;
		}
		return ws_case;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Document doc;
		SAXReader reader = new SAXReader();
		try {
			doc = reader.read(new File("data/test_case/1.xml"));
			Element root = doc.getRootElement();
			
			TestCase ws_case = new TestCase();
			
			Node id = root.selectSingleNode(Constants.XML_TEST_CASE_ID);
			if (id != null) {
				// System.out.println(id.getStringValue());
				ws_case.setId(id.getStringValue());
			}
			Node inputTypes = root.selectSingleNode(Constants.XML_TEST_CASE_INPUTTYPES);
			if (inputTypes != null ) {
				// System.out.println(inputTypes.getStringValue());
				ws_case.setInputTypes(inputTypes.getStringValue());
			}
			Node outputTypes = root.selectSingleNode(Constants.XML_TEST_CASE_OUTPUTTUPES);
			if (outputTypes != null) {
				// System.out.println(outputTypes.getStringValue());
				ws_case.setOutput(outputTypes.getStringValue());
			}
			Node category = root.selectSingleNode(Constants.XML_TEST_CASE_CATEGORY);
			if (category != null) {
				// System.out.println(category.getStringValue());
				ws_case.setCategory(category.getStringValue());
			}
			Node service_id = root.selectSingleNode(Constants.XML_TEST_CASE_SERVICE_ID);
			if (service_id != null ) {
				ws_case.setService_id(service_id.getStringValue());
			}
			Node method = root.selectSingleNode(Constants.XML_TEST_CASE_METHOD);
			if (method != null) {
				ws_case.setMethod(method.getStringValue());
			}
			List<Element> props = root.selectNodes(Constants.XML_TEST_CASE_PROPERTIES_PATH);
			if (props.size() > 0) {
				for (int i = 0; i < props.size(); i++) {
					String key = props.get(i).attributeValue(Constants.XML_TEST_CASE_PROP_PROP_NAME);
					Object value = convertStrToObj(props.get(i).attributeValue(Constants.XML_TEST_CASE_PROP_PROP_VALUE),
							props.get(i).attributeValue(Constants.XML_TEST_CASE_PROP_DATA_TYPE));
					ws_case.addProperty(key, value);
				}
			}
			List<Element> configs = root.selectNodes(Constants.XML_TEST_CASE_CONFIGS_PATH);
			if (configs.size() > 0) {
				for (int i = 0; i < configs.size(); i++) {
					TestCaseConfig config = new TestCaseConfig();
					config.setHost(configs.get(i).attributeValue(Constants.XML_TEST_CASE_CONFIGS_HOST));
					config.setThreadCount(Integer.parseInt(configs.get(i).attributeValue(Constants.XML_TEST_CASE_CONFIGS_THREADCOUNT)));
					ws_case.addConfig(config);
				}
			}
			System.out.println("OVER!");
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private static Object convertStrToObj(String value, String type) {
		try {
			if (type.equals("int")) {
				return Integer.parseInt(value);
			} else if (type.equals("long")) {
				return Long.parseLong(value);
			} else if (type.equals("string")) {
				return value;
			} else if (type.equals("char")) {
				if (value.length() != 1) {
					return null;
				} else {
					return value.charAt(0);
				}
			} else if (type.equals("bool")) {
				return Boolean.parseBoolean(value);
			} else if (type.equals("shot")) {
				return Short.parseShort(value);
			} else if (type.equals("byte")) {
				return Byte.parseByte(value);
			} else if (type.equals("float")) {
				return Float.parseFloat(value);
			} else if (type.equals("double")) {
				return Double.parseDouble(value);
			} else {
				return null;
			} } catch (Exception e) {
				return null;
			}
	}
	
}
